package org.luckyjourney.util;

import com.google.common.hash.Funnel;
import com.google.common.hash.Funnels;
import com.google.common.hash.Hashing;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;

/**
 * 布隆过滤器工具类
 */
@Component
public class BloomFilterHelper {
    private int numHashFunctions;
    private int bitSize;
    private Funnel<CharSequence> funnel;

    public BloomFilterHelper() {
        // 预计插入量为10000，误判率为0.01
        this(10000, 0.01);
    }

    public BloomFilterHelper(int expectedInsertions, double fpp) {
        this.bitSize = optimalNumOfBits(expectedInsertions, fpp);
        this.numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, bitSize);
        this.funnel = Funnels.stringFunnel(Charset.defaultCharset());
    }

    public int[] murmurHashOffset(String value) {
        int[] offset = new int[numHashFunctions];

        long hash64 = Hashing.murmur3_128().hashObject(value, funnel).asLong();
        int hash1 = (int) hash64;
        int hash2 = (int) (hash64 >>> 32);

        for (int i = 1; i <= numHashFunctions; i++) {
            int nextHash = hash1 + i * hash2;
            if (nextHash < 0) {
                nextHash = ~nextHash;
            }
            offset[i - 1] = nextHash % bitSize;
        }

        return offset;
    }

    private int optimalNumOfBits(long n, double p) {
        return (int) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
    }

    private int optimalNumOfHashFunctions(long n, long m) {
        return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));
    }
} 